#include<stdio.h>
#include<stdlib.h>
#include <pthread.h>
#include <unistd.h>

pthread_mutex_t mut;
pthread_cond_t cond;

// //静态初始化
// pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
// pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

void* task1(void* avg);
void* task2(void* avg);

// 条件
// 0 未准备就绪
// 1 准备就绪

int if_ready = 0;

int main()
{
    //动态初始化
    pthread_mutex_init(&mut, NULL);
    pthread_cond_init(&cond, NULL);

    //创建两个线程
    pthread_t tid1, tid2;
    pthread_create(&tid1, NULL, task1, NULL);
    pthread_create(&tid2, NULL, task2, NULL);

    // 主线程等待子线程结束
    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);
    //销毁
    pthread_mutex_destroy(&mut);
    pthread_cond_destroy(&cond);
    return 0;
}

void* task1(void* avg)
{
    pthread_mutex_lock(&mut);
    //使用while进行条件检查，避免系统错误或其他原因意外终止,通过while循环来防止虚假唤醒
    while(!if_ready)
    {
        printf("线程 1 执行，但是条件未准备就绪..！\n");
        //释放锁，进入阻塞状态,一定要在释放锁之后调用
        pthread_cond_wait(&cond, &mut);
    }
    printf("线程 1 执行，条件就绪\n执行任务，任务完成\n");
    pthread_mutex_unlock(&mut);
}

void* task2(void* avg)
{
    printf("线程 2 启动开始准备...\n");
    sleep(3);
    pthread_mutex_lock(&mut);
    //条件就绪
    if_ready = 1;
    printf("线程 2 启动，准备就绪!\n");
    // 唤醒
    //至少唤醒一个
    // pthread_cond_signal(&cond);
    // 广播的形式唤醒
    pthread_cond_broadcast(&cond);
    pthread_mutex_unlock(&mut);
}
